home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 1 / PC Actual CD 01.iso / f1 / func3d.arj / FUENTE / IMPR.CP_ / IMPR.CP
Encoding:
Text File  |  1994-05-05  |  12.6 KB  |  551 lines

  1. //
  2. //   Fichero: IMPR.CPP
  3. //
  4. //   Versi≤n: 1.0
  5. //     Autor: Antonio M. EstΘvez Lorenzo
  6. // Prop≤sito: Envφa documentos a la impresora
  7. //            Configura la impresora
  8. //
  9.  
  10. #include <windows.h>
  11. #include <owl.h>
  12. #pragma  hdrstop
  13.  
  14. #include "impr.h"
  15. #include "strings.h"
  16. #include <static.h>
  17.  
  18. static BOOL Abortado= FALSE;
  19. static BOOL UsarBandInfo;
  20. static HDC  ImprDC;
  21. static WORD Flags;
  22. static BOOL Primera;
  23. static RECT BandRect;
  24. static SIZE DimPagina;
  25.  
  26. BOOL FAR PASCAL _export AbortProc(HDC, short)
  27. {
  28.   MSG Msg;
  29.  
  30.   while(!Abortado && PeekMessage(&Msg, NULL, NULL, NULL, PM_REMOVE))
  31.   {
  32.      TranslateMessage(&Msg);
  33.      DispatchMessage(&Msg);
  34.   }
  35.   return (!Abortado);
  36. }
  37.  
  38. static void CreaDriverStr(Pchar DriverStr, int MaxLen,
  39.                           Pchar Device, Pchar Port)
  40. {
  41.    StrCpy(DriverStr, Device);
  42.    LoadString(GetApplicationObject()->hInstance, SR_ON,
  43.              (DriverStr + LongStr(DriverStr)), MaxLen-LongStr(DriverStr)-1);
  44.    StrUne(DriverStr, DriverStr, Port);
  45. }
  46.  
  47.  
  48. /* TDatosImpr */
  49.  
  50. TDatosImpr::TDatosImpr(Pchar dispos, Pchar driver, Pchar puerto, TDatosImpr *Ultimo)
  51. {
  52.    Dispos= NewStr(dispos);
  53.    Driver= NewStr(driver);
  54.    Puerto= NewStr(puerto);
  55.    Siguiente= NULL;
  56.    if(Ultimo)
  57.       Ultimo->Siguiente= this;
  58. }
  59.  
  60. TDatosImpr::~TDatosImpr()
  61. {
  62.    delete Dispos;
  63.    delete Driver;
  64.    delete Puerto;
  65.    if(Siguiente)
  66.       delete Siguiente;
  67. }
  68.  
  69.  
  70. /* TImpresora */
  71.  
  72. TImpresora::TImpresora(Pchar titulo)
  73. {
  74.    Titulo= NewStr(titulo);
  75.    Banding= FALSE;
  76.    ForzarTodos= TRUE;
  77. }
  78.  
  79. TImpresora::~TImpresora()
  80. {
  81.    delete Titulo;
  82. }
  83.  
  84. BOOL TImpresora::HayMasPaginas()
  85. {
  86.    return FALSE;
  87. }
  88.  
  89.  
  90. /* TImpr */
  91.  
  92. TImpr::TImpr()
  93. {
  94.    Dispos= NULL;
  95.    Driver= NULL;
  96.    Puerto= NULL;
  97.    ModuloDispos= NULL;
  98.    ConfigDispos= NULL;
  99.    Error= NULL;
  100.    SelecDispos(NULL, NULL, NULL);
  101. }
  102.  
  103. TImpr::~TImpr()
  104. {
  105.    IniciaDispos();
  106. }
  107.  
  108. void TImpr::IniciaDispos()
  109. {
  110.    delete Dispos;
  111.    delete Driver;
  112.    delete Puerto;
  113.    Dispos= Driver= Puerto= NULL;
  114.  
  115.    if((int)ModuloDispos>= 32)
  116.    {
  117.       FreeLibrary(ModuloDispos);
  118.       ModuloDispos= NULL;
  119.    }
  120.    if(ConfigDispos)
  121.       delete [](Pchar) ConfigDispos;
  122.    Estado= IE_NOASOCIADO;
  123. }
  124.  
  125. void TImpr::ImprDefecto()
  126. {
  127.   char Impr[80];
  128.   char DisposStr[70], DriverStr[70], PuertoStr[10];
  129.    
  130.   GetProfileString("windows", "device", "", Impr,sizeof(Impr)-1);
  131.   SeparaParam(Impr,DisposStr,DriverStr,PuertoStr);
  132.   Dispos= NewStr(DisposStr);
  133.   Driver= NewStr(DriverStr);
  134.   Puerto= NewStr(PuertoStr);
  135. }
  136.  
  137. void TImpr::SelecDispos(Pchar dispos, Pchar driver, Pchar puerto)
  138. {
  139.   char NombreDriver[80];
  140.   DEVMODE ModoDisp;
  141.  
  142.   if(StrEqu(Dispos, dispos) &&
  143.      StrEqu(Driver, driver) &&
  144.      StrEqu(Puerto, puerto))
  145.      return;
  146.   IniciaDispos();
  147.   if(dispos == NULL)
  148.      ImprDefecto();
  149.   else
  150.   {
  151.      Dispos= NewStr(dispos);
  152.      Driver= NewStr(driver);
  153.      Puerto= NewStr(puerto);
  154.   }
  155.   Estado = IE_OK;
  156.   StrUne(NombreDriver, Driver, ".DRV");
  157.   ModuloDispos= LoadLibrary(NombreDriver);
  158.   if((int)ModuloDispos< 32)
  159.      Estado= IE_NOVALIDO;
  160.   else
  161.   {
  162.      ModoDisposExt= (LPFNDEVMODE) GetProcAddress(ModuloDispos, "ExtDeviceMode");
  163.      ModoDispos= (PTModoDispos) GetProcAddress(ModuloDispos, "DeviceMode");
  164.      if((ModoDispos== NULL) && (ModoDispos== NULL))
  165.         Estado= IE_NOVALIDO;
  166.      if(ModoDisposExt!= NULL)
  167.      {
  168.         LongConfig= ModoDisposExt(0, ModuloDispos, &ModoDisp,
  169.                                   Dispos, Puerto, &ModoDisp, NULL, 0);
  170.         ConfigDispos= (PDEVMODE) new char[LongConfig];
  171.         ModoDisposExt(0, ModuloDispos, ConfigDispos, Dispos, Puerto,
  172.                            ConfigDispos, NULL, DM_OUT_BUFFER);
  173.      }
  174.     else
  175.        ConfigDispos= NULL; 
  176.   }
  177. }
  178.  
  179. void TImpr::Configurar(PTWindowsObject Window)
  180. {
  181.   if (Estado == IE_OK)
  182.     if(ModoDisposExt== NULL) 
  183.       ModoDispos(Window->HWindow, ModuloDispos, Dispos, Puerto);
  184.     else
  185.       ModoDisposExt(Window->HWindow, ModuloDispos, ConfigDispos, Dispos,
  186.         Puerto, ConfigDispos, NULL, DM_IN_BUFFER | DM_PROMPT | DM_OUT_BUFFER);
  187. }
  188.  
  189. HDC TImpr::GetDC()
  190. {
  191.   if(Estado== IE_OK)
  192.     return CreateDC(Driver, Dispos, Puerto, (LPSTR)(LPDEVMODE)ConfigDispos);
  193.   else
  194.     return NULL;
  195. }
  196.  
  197. SIZE TImpr::DimPaginaMM()
  198. {
  199.    SIZE Dim;
  200.  
  201.    HDC Hdc= GetDC();
  202.    Dim.cx = GetDeviceCaps(Hdc, HORZSIZE);
  203.    Dim.cy = GetDeviceCaps(Hdc, VERTSIZE);
  204.    DeleteDC(Hdc);
  205.    return Dim;
  206. }
  207.  
  208. SIZE TImpr::DimPaginaPixels()
  209. {
  210.    SIZE Dim;
  211.  
  212.    HDC Hdc= GetDC();
  213.    Dim.cx = GetDeviceCaps(Hdc, HORZRES);
  214.    Dim.cy = GetDeviceCaps(Hdc, VERTRES);
  215.    DeleteDC(Hdc);
  216.    return Dim;
  217. }
  218.  
  219. void TImpr::CalcBandingFlags()
  220. {
  221.    struct TBandInfo
  222.    {
  223.       BOOL fGraficos;
  224.       BOOL fTexto;
  225.       RECT GrafRect;
  226.    } BandInfo;
  227.  
  228.    WORD pFlags = 0;
  229.    if(UsarBandInfo)
  230.    {
  231.       Escape(ImprDC, BANDINFO, sizeof(TBandInfo), NULL, (LPSTR)&BandInfo);
  232.       if(BandInfo.fGraficos)
  233.          pFlags= IF_GRAFICOS;
  234.       if(BandInfo.fTexto)
  235.          pFlags= pFlags | IF_TEXTO;
  236.       Flags = (Flags & !IF_AMBOS) | pFlags;
  237.    }
  238.    else
  239.    {
  240.       if((Primera) && (BandRect.left== 0) &&
  241.          (BandRect.top== 0) &&
  242.          (BandRect.right== DimPagina.cx) &&
  243.          (BandRect.bottom== DimPagina.cy))
  244.          Flags = IF_TEXTO;
  245.      else if ((Flags & IF_AMBOS) == IF_TEXTO)
  246.         Flags = ((Flags & !IF_AMBOS) | IF_GRAFICOS);
  247.      else
  248.         Flags = Flags | IF_AMBOS;
  249.    }
  250.    Primera= FALSE;
  251. }
  252.  
  253. BOOL TImpr::Imprime(PTWindowsObject ParentWin, PTImpresora Impresora)
  254. {
  255.    typedef BOOL (FAR PASCAL *PTAbortProc)( HDC Prn, short Code );
  256.  
  257.    BOOL Banding;
  258.    WORD NumeroPagina;
  259.    PTAbortProc AbortProcInst;
  260.    PTWindowsObject Dlg;
  261.  
  262.    BOOL result = FALSE;
  263.  
  264.    Error= NULL;
  265.  
  266.    if((!Impresora) || (!ParentWin))
  267.       return result;
  268.    if(Estado!= IE_OK)
  269.    {
  270.       Error = SP_ERROR;
  271.       InformaError(Impresora);
  272.       return result;
  273.    }
  274.  
  275.    ImprDC = GetDC();
  276.    if(!ImprDC)
  277.       return result;
  278.  
  279.    Dlg= GetApplicationObject()->MakeWindow(new TDlgAbortImpr(
  280.             ParentWin, Impresora->Titulo, Dispos, Puerto));
  281.    if(!Dlg)
  282.    {
  283.       DeleteDC(ImprDC);
  284.       return result;
  285.    }
  286.    EnableWindow(ParentWin->HWindow, FALSE);
  287.  
  288.    AbortProcInst= (PTAbortProc) MakeProcInstance((FARPROC)AbortProc,
  289.                   GetApplicationObject()->hInstance);
  290.    Escape(ImprDC, SETABORTPROC, 0, LPSTR(AbortProcInst), NULL);
  291.  
  292.    DimPagina= DimPaginaPixels();
  293.  
  294.    Banding= (Impresora->Banding  &&
  295.              GetDeviceCaps(ImprDC, RASTERCAPS) & RC_BANDING);
  296.    if(!Banding)
  297.    {
  298.       BandRect.left  = 0;
  299.       BandRect.top   = 0;
  300.       BandRect.right = DimPagina.cx;
  301.       BandRect.bottom= DimPagina.cy;
  302.    }
  303.    else
  304.    {
  305.       Flags = BANDINFO;
  306.       UsarBandInfo =
  307.          Escape(ImprDC, QUERYESCSUPPORT, sizeof(Flags), (LPSTR)&Flags, NULL);
  308.    }
  309.    Flags= IF_AMBOS;
  310.    Error= Escape(ImprDC, STARTDOC, LongStr(Impresora->Titulo),
  311.                  Impresora->Titulo, NULL);
  312.    NumeroPagina= 1;
  313.    if(Error> 0)
  314.    {
  315.       do
  316.       {
  317.          if(Banding)
  318.          {
  319.             Primera= TRUE;
  320.             Error  = Escape(ImprDC, NEXTBAND, 0, NULL, (LPSTR) &BandRect);
  321.          }
  322.          do
  323.          {
  324.             (*AbortProcInst)(ImprDC, 0);
  325.             if(Banding)
  326.             {
  327.                CalcBandingFlags();
  328.                if((Impresora->ForzarTodos) &&
  329.                   ((Flags & IF_AMBOS)== IF_TEXTO))
  330.                   SetPixel(ImprDC, 0, 0, 0);
  331.             }
  332.             if(Error> 0)
  333.             {
  334.                Error= Impresora->ImprimePagina(ImprDC, NumeroPagina,
  335.                                                DimPagina, &BandRect, Flags);
  336.                if((Error> 0) && Banding)
  337.                   Error= Escape(ImprDC, NEXTBAND, 0, NULL, (LPSTR) &BandRect);
  338.             }
  339.          }while ((Error> 0) && (Banding) && (!IsRectEmpty(&BandRect)));
  340.   
  341.          if((Error> 0) && (!Banding))
  342.             Error= Escape(ImprDC, NEWFRAME, 0, NULL, NULL);
  343.          NumeroPagina++;
  344.       }while((Error> 0) && (Impresora->HayMasPaginas()) );
  345.  
  346.       if(Error> 0)
  347.          if(Banding && Abortado)
  348.             Escape(ImprDC, ABORTDOC, 0, NULL, NULL);
  349.          else
  350.             Escape(ImprDC, ENDDOC, 0, NULL, NULL);
  351.       else
  352.          Escape(ImprDC, ABORTDOC, 0, NULL, NULL);
  353.    }
  354.    FreeProcInstance((FARPROC) AbortProcInst);
  355.    EnableWindow(ParentWin->HWindow, TRUE);
  356.    delete Dlg;
  357.    DeleteDC(ImprDC);
  358.  
  359.    if(Error & SP_NOTREPORTED )
  360.      InformaError(Impresora);
  361.    result= (Error> 0) && (!Abortado);
  362.    Abortado= FALSE;
  363.    return result;
  364. }
  365.  
  366. void TImpr::InformaError(PTImpresora Impresora)
  367. {
  368.   WORD ErrorId;
  369.   switch (Error)
  370.   {
  371.     case SP_APPABORT:
  372.       ErrorId = SR_PRNCANCEL;
  373.       break;
  374.     case SP_ERROR:
  375.       ErrorId = SR_GENERROR;
  376.       break;
  377.     case SP_OUTOFDISK:
  378.       ErrorId = SR_OUTOFDISK;
  379.       break;
  380.     case SP_OUTOFMEMORY:
  381.       ErrorId = SR_OUTOFMEMORY;
  382.       break;
  383.     case SP_USERABORT:
  384.       ErrorId = SR_PRNMGRABORT;
  385.       break;
  386.     default:
  387.       ErrorId = -Error;
  388.   }
  389.   Mensaje(NULL, ErrorId, MensError, MB_ICONSTOP | MB_OK, (LPSTR)Impresora->Titulo);
  390. }
  391.  
  392.  
  393. /* TDlgConfigImpr */
  394.  
  395. #define prLongStr   80
  396. #define DimDispos 1000
  397.  
  398. TDlgConfigImpr::TDlgConfigImpr(PTWindowsObject parent, int ResID, PTImpr impr)
  399.                :TWindDlg(parent, ResID)
  400. {
  401.    ListImpr = new TComboBox(this, idCombo, prLongStr);
  402.    Impr= impr;
  403.    DatosImpr= NULL;
  404. }
  405.  
  406. void TDlgConfigImpr::SetupWindow()
  407. {
  408.    TWindDlg::SetupWindow();
  409.  
  410.    Pchar LstDisposStr;
  411.    Pchar StrCur;
  412.    Pchar Dispos;
  413.    char  Driver[prLongStr];
  414.    char  Puerto[prLongStr];
  415.    char  DriverStr[prLongStr];
  416.    char  PuertoStr[prLongStr];
  417.    TDatosImpr *Ultimo= NULL;
  418.  
  419.    LstDisposStr= new char[DimDispos];
  420.    tmpDatosImpr= new TDatosImpr(Impr->Dispos, Impr->Driver, Impr->Puerto);
  421.  
  422.    GetProfileString("devices", NULL, "", LstDisposStr, DimDispos);
  423.    Dispos= LstDisposStr;
  424.    while(*Dispos!= '\0')
  425.    {
  426.       GetProfileString("devices", Dispos, "", Driver, sizeof(Driver)-1);
  427.       CreaDriverStr(DriverStr, sizeof(DriverStr)- 1, Dispos, "");
  428.       StrCur= (DriverStr + LongStr(DriverStr));
  429.       StrSep(Driver, Puerto, ',');
  430.       StrSep(Puerto, PuertoStr, ',');
  431.       while(Puerto[0]!= '\0' )
  432.       {
  433.          StrCpy(StrCur, Puerto);
  434.          Ultimo= new TDatosImpr(Dispos, Driver, Puerto, Ultimo);
  435.          if(!DatosImpr)
  436.             DatosImpr= Ultimo;
  437.          ListImpr->AddString(DriverStr);
  438.          StrCpy(Puerto, PuertoStr);
  439.          StrSep(Puerto, PuertoStr, ',');
  440.       }
  441.       Dispos+= (LongStr(Dispos)+1);
  442.    }
  443.    delete LstDisposStr;
  444.    if(*(Impr->Dispos)!= '\0')
  445.        CreaDriverStr(DriverStr, prLongStr, Impr->Dispos, Impr->Puerto);
  446.    else
  447.        DriverStr[0] = '\0';
  448.    ListImpr->SetText(DriverStr);
  449. }
  450.  
  451.  
  452. TDlgConfigImpr::~TDlgConfigImpr( void )
  453. {
  454.    delete DatosImpr;
  455.    delete tmpDatosImpr;
  456. }
  457.  
  458. void TDlgConfigImpr::Configurar()
  459. {
  460.    TDatosImpr *pDatos= DatosImpr;
  461.    int Index= ListImpr->GetSelIndex();
  462.  
  463.    if(Index>= 0)
  464.    {
  465.       for(int i=0; i< Index; i++)
  466.          pDatos= pDatos->Siguiente;
  467.       Impr->SelecDispos(pDatos->Dispos, pDatos->Driver, pDatos->Puerto);
  468.    }
  469. }
  470.  
  471. void TDlgConfigImpr::Config(RTMessage)
  472. {
  473.    Configurar();
  474.    Impr->Configurar(this);
  475. }
  476.  
  477. void TDlgConfigImpr::Ok(RTMessage Msg)
  478. {
  479.    Configurar();
  480.    TWindDlg::Ok(Msg);
  481. }
  482.  
  483. void TDlgConfigImpr::Cancel(RTMessage Msg)
  484. {
  485.    TWindDlg::Cancel(Msg);
  486.    if(tmpDatosImpr->Driver== NULL)
  487.       Impr->IniciaDispos();
  488.    else
  489.       Impr->SelecDispos(tmpDatosImpr->Dispos, tmpDatosImpr->Driver,
  490.                         tmpDatosImpr->Puerto);
  491. }
  492.  
  493.  
  494. /* TReplaceStatic */
  495.  
  496. _CLASSDEF(TRepStatic)
  497. class TRepStatic: public TStatic
  498. {
  499.   Pchar Text;
  500. protected:
  501.    void SetupWindow();
  502. public:
  503.    TRepStatic(PTWindowsObject parent, int resId, Pchar text);
  504.   ~TRepStatic();
  505. };
  506.  
  507. TRepStatic::TRepStatic(PTWindowsObject parent, int resID, Pchar text)
  508.            :TStatic(parent, resID, 0)
  509. {
  510.    Text= NewStr(text);
  511. }
  512.  
  513. TRepStatic::~TRepStatic()
  514. {
  515.    delete Text;
  516. }
  517.  
  518. void TRepStatic::SetupWindow()
  519. {
  520.    char St1[80];
  521.    char St2[80];
  522.  
  523.    TStatic::SetupWindow();
  524.    GetText(St1, sizeof(St1) - 1);
  525.    wsprintf(St2, St1, Text);
  526.    SetText(St2);
  527. }
  528.  
  529.  
  530. /* TDlgAbortImpr */
  531.  
  532. TDlgAbortImpr::TDlgAbortImpr(PTWindowsObject parent, Pchar Titulo,
  533.                              Pchar Dispos, Pchar Puerto)
  534.               :TWindDlg(parent, dgAbortImpr)
  535. {
  536.    new TRepStatic(this, idTitulo, Titulo);
  537.    new TRepStatic(this, idDispos, Dispos);
  538.    new TRepStatic(this, idPuerto, Puerto);
  539. }
  540.  
  541. void TDlgAbortImpr::SetupWindow()
  542. {
  543.    TWindDlg::SetupWindow();
  544.    EnableMenuItem(GetSystemMenu(HWindow, FALSE), SC_CLOSE, MF_GRAYED);
  545. }
  546.  
  547. void TDlgAbortImpr::WMCommand(RTMessage)
  548. {
  549.    Abortado= TRUE;
  550. }
  551.